package com.eb.utils;

import java.security.MessageDigest;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

/**
 * 加密工具类
 * @author Administrator
 * md5 3des 
 */
public class EncryptUtil {
	
	private static final String encrytkey = "CD5A81F9010A094CDBF1CB0C04345F16E2053A77D46D072E";
	
	//*******************************3DES加解密*********************************//
	
	/**
	 * des3加密
	 * @param des3
	 * @return
	 */
	public static String encodeDes3(String des3) {
		try {
			String key = encrytkey;
			return Des3Str(key, des3);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 3DES解密
	 * @throws Exception 
	 */
	public static String decodeDes3(String des3){
		try {
			/**
			 * 秘钥
			 * */
			String key = encrytkey;
			String result = UnDes3Str(key, des3);
			
			return result;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public static String toAddKey(String key){
		String str = key;
		int n = 48 - key.length();
		if(n > 0){
			str += str.substring(0, n);
		}
		return str;  
	}
	public static byte[] hexByte(byte[] b) {
		if ((b.length % 2) != 0){
    		throw new IllegalArgumentException("长度不是偶数");
    	}
    	byte[] b2 = new byte[b.length / 2];
    	for (int n = 0; n < b.length; n += 2) {
    		String item = new String(b, n, 2);
    		b2[n / 2] = (byte) Integer.parseInt(item, 16);
    	}
    	return b2;
	}
	public static String byteHex(byte[] b) {
		String hs="";
        String stmp="";

        for (int n=0;n<b.length;n++) {
            stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length()==1){
           		hs=hs+"0"+stmp;
           }else{
            	hs=hs+stmp;
           }
        }
        return hs.toUpperCase();
	}
	   
	public static byte[] toDecryptMode(byte[] data,byte[] key) throws Exception{
		
		byte[] DecByte=null;
		try {
			SecretKey deskey = new SecretKeySpec(key, "DESede");
			Cipher cipher = Cipher.getInstance("DESede/ECB/NOPADDING");
//			Cipher cipher = Cipher.getInstance("DESede");
			cipher.init(Cipher.DECRYPT_MODE, deskey);
			DecByte=cipher.doFinal(data);
		} catch (Exception e) {
			throw e;
		}
		return DecByte;
	}
	
	public static String UnDes3Str(String key,String src) throws Exception{
		byte[] keyStr = toAddKey(key).getBytes();
		byte[] keyBytes=hexByte(keyStr);
		byte[] cSrcBytes = toDecryptMode(hexByte(src.getBytes()), keyBytes);
		String hexStr=byteHex(cSrcBytes);
		/**
		* 	将解密后字符串的后面的00去掉
		**/
		int len_new=hexStr.length();
		int len_old=len_new;
		for(int i=0;i<8;i++)
		{	
			len_old=len_new;
			hexStr=hexStr.replaceAll("00$", "");//c++加密补位在后面加00
		    hexStr=hexStr.replaceAll("06$", "");//java加密补位在后面加06
		    hexStr=hexStr.replaceAll("08$", "");
		    len_new=hexStr.length();
		    if(len_new==len_old)
		      	break;        
		}
		 byte[] DecByte=hexByte(hexStr.getBytes());
		 byte[] newtemp=new String(DecByte,"gbk").getBytes("utf-8");//这里写转换后的编码方式
         String newStr=new String(newtemp,"utf-8");//这里写转换后的编码方式
		return newStr;
	}
	/**
     *  转化字符串为十六进制编码
     */
	public static String toHexString(String s)   
	{   
		String str="";   
		for (int i=0;i<s.length();i++)   
		{   
			int ch = (int)s.charAt(i);   
			String s1 = Integer.toHexString(ch);   
			str = str + s1; 
		} 
		//自动添加补位00
		if((s.length())%8>0){
			int n=8-(s.length())%8;
			while((n--) >0){
				str+="00";
			}
		}
		return str;   
	} 
	
	public static String Des3Str(String key,String src) throws Exception{
		byte[] keyStr = toAddKey(key).getBytes();
		byte[] keyBytes=hexByte(keyStr);
		byte[] sData=src.getBytes();
		sData=new String(sData,"UTF-8").getBytes("GBK");//这里写转换后的编码方式
		byte[] desData=sData;
		if(sData.length%8!=0){
			desData=new byte[(1+sData.length/8)*8];
			System.arraycopy(sData,0,desData,0,sData.length);
		}
		
		byte[] cSrcBytes = toEncryptMode(desData, keyBytes);
		String hexStr=byteHex(cSrcBytes);
		return hexStr;
	}
	/**
	 * 3DES加密
	 * */
	public static byte[] toEncryptMode(byte[] data,byte[] key) throws Exception{
		
		byte[] EncByte=null;
		try {
			SecretKey deskey = new SecretKeySpec(key, "DESede");
			Cipher cipher = Cipher.getInstance("DESede/ECB/NOPADDING");
			cipher.init(Cipher.ENCRYPT_MODE, deskey);
			EncByte=cipher.doFinal(data);
		} catch (Exception e) {
			throw e;
		}
		return EncByte;
	}
	//*******************************MD5*********************************//
	
		public static String MD5(String origin) throws Exception{
	        String resultString = null;
	        resultString = new String(origin);
	        MessageDigest md;
	        try{
	            md = MessageDigest.getInstance("MD5");
	        }catch(Exception e){
	            throw new RuntimeException(e);
	        }
            resultString = Hex.encodeHexString(md.digest(resultString.getBytes("UTF-8")));
	        return resultString;
	    }
		
	 	//*******************************SHA*********************************//
		/**
		 * 32位
		 * @param inStr
		 * @return
		 * @throws Exception
		 */
	    public static String SHA(String inStr) throws Exception {
	        MessageDigest sha = null;
	        try {
	            sha = MessageDigest.getInstance("SHA");
	        } catch (Exception e) {
	            System.out.println(e.toString());
	            e.printStackTrace();
	            return "";
	        }

	        byte[] byteArray = inStr.getBytes("UTF-8");
	        byte[] md5Bytes = sha.digest(byteArray);
	        StringBuffer hexValue = new StringBuffer();
	        for (int i = 0; i < md5Bytes.length; i++) {
	            int val = ((int) md5Bytes[i]) & 0xff;
	            if (val < 16) { 
	                hexValue.append("0");
	            }
	            hexValue.append(Integer.toHexString(val));
	        }
	        return hexValue.toString();
	    }
	    
	    //*******************************AES*********************************//
	    /**
	     * 加密
	     * 
	     * @param content
	     *            待加密内容
	     * @param key
	     *            加密的密钥
	     * @return
	     */
	    public static String encodeAES(String content, String key) {
	        try {
	            KeyGenerator kgen = KeyGenerator.getInstance("AES");
	            kgen.init(128, new SecureRandom(key.getBytes()));
	            SecretKey secretKey = kgen.generateKey();
	            byte[] enCodeFormat = secretKey.getEncoded();
	            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
	            Cipher cipher = Cipher.getInstance("AES");
	            byte[] byteContent = content.getBytes("utf-8");
	            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
	            byte[] byteRresult = cipher.doFinal(byteContent);
	            StringBuffer sb = new StringBuffer();
	            for (int i = 0; i < byteRresult.length; i++) {
	                String hex = Integer.toHexString(byteRresult[i] & 0xFF);
	                if (hex.length() == 1) {
	                    hex = '0' + hex;
	                }
	                sb.append(hex.toUpperCase());
	            }
	            return sb.toString();
	        } catch (Exception e) {
	            e.printStackTrace();
	        } 
	        return null;
	    }
	    
	    /**
	     * 解密
	     * 
	     * @param content
	     *            待解密内容
	     * @param key
	     *            解密的密钥
	     * @return
	     */
	    public static String decodeAES(String content, String key) {
	        if (content.length() < 1)
	            return null;
	        byte[] byteRresult = new byte[content.length() / 2];
	        for (int i = 0; i < content.length() / 2; i++) {
	            int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
	            int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
	            byteRresult[i] = (byte) (high * 16 + low);
	        }
	        try {
	            KeyGenerator kgen = KeyGenerator.getInstance("AES");
	            kgen.init(128, new SecureRandom(key.getBytes()));
	            SecretKey secretKey = kgen.generateKey();
	            byte[] enCodeFormat = secretKey.getEncoded();
	            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
	            Cipher cipher = Cipher.getInstance("AES");
	            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
	            byte[] result = cipher.doFinal(byteRresult);
	            return new String(result);
	        } catch (Exception e) {
	            e.printStackTrace();
	        } 
	        return null;
	    }
	 
	 	//*******************************BASE64*********************************//
	    
	    public static String encodeBase64(String str){
	    	String str1 = new String(Base64.encodeBase64(str.getBytes()));
	    	return str1;
	    }
	    
	    public static String decodeBase64(String str){
	    	String str1 = new String(Base64.decodeBase64(str.getBytes()));
	    	return str1;
	    }
	    
		public static void main(String[] args) throws Exception {
			String uname = encodeDes3("amigoxiexiexingxing");
			System.out.println(uname);
			System.out.println(decodeDes3(uname));
			System.out.println(MD5("amigoxiexiexingxing"));
			System.out.println(SHA("amigoxiexiexingxing"));
			System.out.println(encodeBase64("amigoxiexiexingxing"));
			System.out.println(decodeBase64("YW1pZ294aWV4aWV4aW5neGluZw=="));
			System.out.println(encodeAES("amigoxiexiexingxing", "key"));
			System.out.println(decodeAES("D011D3CA803749633419DA0B378986CAFA099ECE988AC7A66EDA05FE7C665696", "key"));
		}
}
